#ifndef XTC_FILER_H
#define XTC_FILER_H
#include <string>
#include <mili/mili.h>
#define CPLUSPLUS
#include <xdrfile/xdrfile_xtc.h>
#undef CPLUSPLUS
#include "prot-filer/base.h"

namespace prot_filer
{

typedef float Matrix[DIM][DIM];

class XtcReader: public Coord3DReader, public FormatMixin, private mili::NonCopyable
{
public:
    XtcReader() :
        xfp(NULL),
        filename(),
        _atoms_in_a_protein(0)
    {}
    bool open(const std::string& name)
    {
        return FormatMixin::open(name);
    }
    void close()
    {
        FormatMixin::close();
    }

    inline bool read(BasicProtein& protein);
    inline bool read(Protein& protein);

    size_t get_atom_number() const
    {
        return _atoms_in_a_protein;
    }
private:
    bool _open(const std::string& name);
    void _close();
    template<class T>
    bool read(T& protein);
private:
    XDRFILE* xfp;
    std::string filename;
    int _atoms_in_a_protein;
};

class XtcWriter: public FormatWriter, private mili::NonCopyable
{
private:
    typedef unsigned int XtcStep;
public:
    XtcWriter() :
        step_number(0),
        _TIME_START(1.0f),
        _TIME_STEP(1.0f),
        _time(_TIME_START),
        xfp(NULL)
    {
        initialize();
    }
    void write(BasicProtein& patm, const AnglesData& angles_data);
    void write(const Protein& protein);
    void write(const std::vector<Coord3d>& backbone);
    ~XtcWriter() {};
private:
    void initialize();
    bool _open(const std::string& name);
    void writextc(BasicProtein& patm, int nres);
    void _close();
    void take_step();
private:
    XtcStep step_number;
    const float _TIME_START;
    const float _TIME_STEP;
    float _time;
    XDRFILE* xfp;
    Matrix default_box;
};
}
#endif
